home *** CD-ROM | disk | FTP | other *** search
/ CICA 1993 April / CICA MS Windows - April 1993.iso / unzipped / programr / vbasic / hugary / hugearr.c < prev    next >
C/C++ Source or Header  |  1992-03-11  |  28KB  |  769 lines

  1. /************************************************************************
  2. *                                                                       *
  3. *                               HUGEARR.DLL                             *
  4. *                                                                       *
  5. *               Huge array support for Microsoft Visual Basic           *
  6. *                                                                       *
  7. *                             By Mike Warning                           *
  8. *                                    *
  9. *   Modifications by Jonathan Zuck.                    *
  10. *   Modifications by Stephen Schmidt.                    *
  11. *   Modifications by End User Computing, Ltd.                *
  12. *                                                                       *
  13. ************************************************************************/
  14.  
  15. #include <memory.h>
  16. /* Define NOCOMM so that MSC compiler does not generate messages using Warning Level 4. */
  17. #define NOCOMM
  18. #include <windows.h>
  19.  
  20.  
  21. struct ArrayDesc  {
  22.     HANDLE  handle;   /* handle to global memory array */
  23.     int     recsize;  /* record size of array */
  24.     long    ubound;   /* upper bound of array */
  25.     int     perseg;   /* #elements per segment */
  26.     int     redim;    /* whether or not GlobalRealloc was successful */
  27.     long    bsize;    /* actual size in bytes of memory block allocated for array element storage */
  28. };
  29.  
  30. typedef struct ArrayDesc *pDescrip;
  31. typedef double currency;  /* currency and double are the same size and will be treated the same */
  32.  
  33. /* All of the C comments which begin with "VBI:" or "VBB:" are placed into the files HUGEARR.VBI
  34.    and HUGEARR.BAS. */
  35. /* VBI: ' An alternate set of definitions with more consistent names that you may want */
  36. /* VBI: ' to consider using instead of those in HUGEARR.BAS. */
  37. /* VBI:  Global Const HA_OK              = 0 */
  38. /* VBI:  Global Const HA_OUTOFMEMORY    = -1 */
  39. /* VBI:  Global Const HA_TOMANYARRAYS   = -2 */
  40. /* VBI:  Global Const HA_BADELEMENTSIZE = -3  ' no longer possible; left for backward compatibility. */
  41. /* VBI:  Global Const HA_SUBSCRIPT      = -4 */
  42. /* VBI:  Global Const HA_BADARRAY       = -5 */
  43. /* VBI:  Global Const HA_FILEOPENERROR  = -7 */
  44. /* VBI:  Global Const HA_FILEWRITEERROR = -8 */
  45. /* VBI:  Global Const HA_FILEREADERROR  = -9 */
  46.  
  47. /* VBB: ' The original set of definitions. */
  48. /* VBB:  Global Const HA_OK              = 0 */
  49. /* VBB:  Global Const HA_OUTOFMEMORY    = -1 */
  50. /* VBB:  Global Const HA_TOMANYARRAYS   = -2 */
  51. /* VBB:  Global Const HA_BADELEMENTSIZE = -3  ' no longer possible; left for backward compatibility. */
  52. /* VBB:  Global Const HA_SUBSCRIPT      = -4 */
  53. /* VBB:  Global Const HA_BADARRAY       = -5 */
  54. /* VBB:  Global Const HA_FILEOPENERROR  = -7 */
  55. /* VBB:  Global Const HA_FILEWRITEERROR = -8 */
  56. /* VBB:  Global Const HA_FILEREADERROR  = -9 */
  57.  
  58. #define HA_OK              0
  59. #define HA_OUTOFMEMORY    -1
  60. #define HA_TOMANYARRAYS   -2
  61. #define HA_BADELEMENTSIZE -3  /* no longer possible; left for backward compatibility */
  62. #define HA_SUBSCRIPT      -4
  63. #define HA_BADARRAY       -5
  64. #define HA_FILEOPENERROR  -7
  65. #define HA_FILEWRITEERROR -8
  66. #define HA_FILEREADERROR  -9
  67.  
  68.  
  69. HANDLE hLocalMem;  /* handle to local memory */
  70. int    NumArrays;  /* total number of arrays */
  71.  
  72. /************************************************************************
  73. * LibMain -                                                             *
  74. *   Standard DLL constructor.  Allocates all of local heap to store     *
  75. * array descriptors and then set the total number of arrays possible.   *
  76. ************************************************************************/
  77. int FAR pascal _export
  78. LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
  79.     {
  80.     if (cbHeapSize > 0)
  81.         UnlockData(0);
  82.  
  83.     /* Allocate memory for array descrips. */
  84.     hLocalMem = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, LocalCompact((WORD) 65500));
  85.     if (hLocalMem == NULL)
  86.         /* Something happened, bomb out */
  87.         return 0;
  88.  
  89.     /* calc total number of arrays */
  90.     NumArrays = (int) (LocalSize(hLocalMem) / sizeof(struct ArrayDesc));
  91.  
  92.     return 1;
  93.     }
  94.  
  95. /************************************************************************
  96. * WEP -                                                                 *
  97. *   Standard DLL destructor.  Free up local memory and quit.            *
  98. ************************************************************************/
  99. int FAR pascal _export
  100. WEP(int bSystemExit)
  101.     {
  102.     LocalFree(hLocalMem);
  103.     return 1;
  104.     }
  105.  
  106. /********************************************************************
  107. * GetFreeArray -                                                    *
  108. *   Searches the array descriptor table looking for a free entry.   *
  109. * It returns the index into the table if an entry is free or        *
  110. * HA_TOMANYARRAYS otherwise.  pArray is the pointer to the start of *
  111. * the table.                                                        *
  112. ********************************************************************/
  113. int
  114. GetFreeArray(pDescrip pArray)
  115.     {
  116.     int i = 0;
  117.  
  118.     /* loop until found or out of entries */
  119.     while (i < NumArrays && pArray -> handle != NULL)
  120.         {
  121.         ++pArray;
  122.         ++i;
  123.         }
  124.  
  125.     if (i == NumArrays)
  126.         /* didn't find a spot */
  127.         return HA_TOMANYARRAYS;
  128.  
  129.     /* found one, return index to it */
  130.     return i;
  131.     }
  132.  
  133. #define HugeElementOffset(ELEMNO, PERSEG, RECSIZE)    \
  134.       ELEMNO / (long) PERSEG * 0x10000L        \
  135.     + ELEMNO % (long) PERSEG * (long) RECSIZE
  136.  
  137. /********************************************************************
  138. *   HugeAlloc -                                                     *
  139. * Allocates (or reallocates) global memory for an array.  The size  *
  140. * of the array is recsize * (ubound + 1) bytes.  The information    *
  141. * for the array is stored in the array descriptor pointed to by     *
  142. * 'pArray'.                                                         *
  143. ********************************************************************/
  144. int
  145. HugeAlloc(pDescrip pArray, int recsize, long ubound, BOOL realloc)
  146.     {
  147.     int    perseg;  /* #elements per segment */
  148.     long   newsiz;  /* actual size of array */
  149.     HANDLE handle;  /* temp handle for alloc */
  150.  
  151.     /* ubound = #elements - 1 */
  152.     ++ubound;
  153.  
  154.     /* #elements per segment. */
  155.     perseg = (int) (0x10000L / (long) recsize);
  156.     /* size of array in bytes */
  157.         newsiz = HugeElementOffset(ubound, perseg, recsize);
  158.  
  159.     if (!realloc)
  160.         /* allocate a new array */
  161.         handle = GlobalAlloc(GMEM_MOVEABLE || GMEM_ZEROINIT, newsiz);
  162.     else
  163. #ifndef REDIMUAES
  164.         /* attempt to reallocate the existing array */
  165.         /* TO HUGEARR USERS RECEIVING UAE'S DURING CALLS TO HugeRedim:  Define REDIMUAES somehow then recompile. */
  166.         if ((handle = GlobalReAlloc(pArray -> handle, newsiz, GMEM_MOVEABLE || GMEM_ZEROINIT)) != NULL)
  167.             pArray -> redim = TRUE;
  168.         else
  169. #endif
  170.             /* existing array could not be reallocated--attempt to create a new one */
  171.             if ((handle = GlobalAlloc(GMEM_MOVEABLE || GMEM_ZEROINIT, newsiz)) != NULL)
  172.                 /* new array to replace the existing one was allocated okay */
  173.                 {
  174.                 BYTE _huge *FmBegin;
  175.                 BYTE _huge *ToBegin;
  176.                 long        numcopy;  /* minimum of #elements in old & new array */
  177.                 long        curelem;  /* current element during copy */
  178.                 long        ElemOff;  /* offset of current elements for copy */
  179.  
  180.                 /* get pointers to the beginning of the existing and new arrays */
  181.                 FmBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
  182.                 ToBegin = (BYTE _huge *) GlobalLock(handle);
  183.                 /* size of original array is pArray->ubound + 1; size of new one is ubound */
  184.                 numcopy  = (ubound < pArray->ubound + 1L) ? ubound : pArray->ubound + 1L;
  185.  
  186.                 /* copy each element from old array to new array, up to the min. # of elements in both arrays. */
  187.                 for (curelem = 0; curelem < numcopy; curelem++)
  188.                     {
  189.                     /* byte offset of current numbered element from beginning of memory block */
  190.                     ElemOff = HugeElementOffset(curelem, perseg, recsize);
  191.  
  192.                     _fmemcpy(ToBegin + ElemOff, FmBegin + ElemOff, recsize);
  193.                     }
  194.  
  195.                 GlobalUnlock(handle);
  196.                 GlobalUnlock(pArray -> handle);
  197.                 /* free old array */
  198.                 GlobalFree(pArray -> handle);
  199.                 pArray -> redim = FALSE;
  200.                 }
  201.  
  202.     if (handle == NULL)
  203.         /* out of memory */
  204.         return HA_OUTOFMEMORY;
  205.  
  206.     pArray -> bsize = GlobalSize(handle);
  207.     /* save new handle */
  208.     pArray -> handle = handle;
  209.     /* save element size */
  210.     pArray -> recsize = recsize;
  211.     /* ubound = #elements - 1 */
  212.     pArray -> ubound = ubound - 1;
  213.     pArray -> perseg = perseg;
  214.  
  215.     return HA_OK;
  216.     }
  217.  
  218. /************************************************************************
  219. * HugeDim -                                                             *
  220. *   Dimensions a new array.  The size of the array is                   *
  221. * (recsize * ubound+1). Recsize is the size in bytes of each element in *
  222. * the array and ubound is the upper bound of the array. All arrays have *
  223. * a lower bound of 0.                                                   *
  224. ************************************************************************/
  225. /* VBI:  Declare Function MSHugeDim% Lib "hugearr.dll" Alias "HugeDim" (ByVal recsize%, ByVal limit&) */
  226. /* VBB:  Declare Function HugeDim% Lib "hugearr.dll" (ByVal recsize%, ByVal limit&) */
  227. int FAR pascal _export
  228. HugeDim(int recsize, long ubound)
  229.     {
  230.     int      hArray;  /* handle to array to dimension */
  231.     pDescrip pArray;  /* pointer to array descriptor */
  232.     int      ret;     /* return value from HugeAlloc */
  233.  
  234.     pArray = (pDescrip) LocalLock(hLocalMem);
  235.  
  236.     /* find a free array */
  237.     if ((hArray = GetFreeArray(pArray)) == HA_TOMANYARRAYS)
  238.         {
  239.         /* couldn't find one, return error.*/
  240.         LocalUnlock(hLocalMem);
  241.         return HA_TOMANYARRAYS;
  242.         }
  243.  
  244.     /* allocate new array */
  245.     ret = HugeAlloc(pArray + hArray, recsize, ubound, FALSE);
  246.     LocalUnlock(hLocalMem);
  247.  
  248.         /* if an error occured during alloc */
  249.     if (ret < 0)
  250.         /* return the error, else */
  251.         return ret;
  252.     else
  253.         /* return the handle to the array */
  254.         /* VB users think handles start at 1 */
  255.         return hArray + 1;
  256.     }
  257.  
  258. #define DecCheckHandle                     \
  259.     /* VB users think hArray begins at 1 */        \
  260.     if (--hArray < 0 || hArray >= NumArrays)    \
  261.         /* illegal array handle */        \
  262.         return HA_BADARRAY;
  263.  
  264. #define CheckNotAllocYet                \
  265.     if (pArray -> handle == NULL)            \
  266.         {                    \
  267.         /* array hasn't been allocated */    \
  268.         LocalUnlock(hLocalMem);            \
  269.         return HA_BADARRAY;            \
  270.         }
  271.  
  272. #define CheckSubscript(MAX)                \
  273.     if (pArray -> ubound < MAX || element < 0)    \
  274.         {                    \
  275.         /* subscript out of range */        \
  276.         LocalUnlock(hLocalMem);            \
  277.         return HA_SUBSCRIPT;            \
  278.         }
  279.  
  280. /************************************************************************
  281. * HugeRedim -                                                           *
  282. *   Redimenions the given array to have the new 'ubound'.  The old      *
  283. * recsize is kept.  All data in the array is preserved and any new data *
  284. * (created by expanding the array) is initialized to 0.                 *
  285. ************************************************************************/
  286. /* VBI:  Declare Function MSHugeRedim% Lib "hugearr.dll" Alias "HugeRedim" (ByVal hArray%, ByVal limit&) */
  287. /* VBB:  Declare Function HugeRedim% Lib "hugearr.dll" (ByVal hArray%, ByVal limit&) */
  288. int FAR pascal _export
  289. HugeRedim(int hArray, long ubound)
  290.     {
  291.     pDescrip pArray;  /* pointer to array desciptor */
  292.     register ret;     /* return code of HugeAlloc */
  293.  
  294.     DecCheckHandle
  295.  
  296.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  297.  
  298.     if (pArray -> handle != NULL)
  299.         /* reallocate array */
  300.         ret = HugeAlloc(pArray, pArray -> recsize, ubound, TRUE);
  301.     else
  302.         /* array has never been allocated */
  303.         ret = HA_BADARRAY;
  304.  
  305.     LocalUnlock(hLocalMem);
  306.     return ret;
  307.     }
  308.  
  309. /********************************************************************
  310. * GetHugeEl -                                                       *
  311. *   Retrieves an element of the array storing it into the buffer    *
  312. * pointed to by 'buffer'.  hArray is the index into the descriptor  *
  313. * table of the array, element is the element to get.                *
  314. *                                                                   *
  315. * NOTE: there is absolutely no type checking done on the buffer.    *
  316. *       It is up to the programmer to make sure it points to the    *
  317. *       correct data type.                                          *
  318. ********************************************************************/
  319. /* VBI:  Declare Function MSHugeGet% Lib "hugearr.dll" Alias "GetHugeEl" (ByVal Index%, ByVal el&, buffer As Any) */
  320. /* VBB:  Declare Function GetHugeEl% Lib "hugearr.dll" (ByVal Index%, ByVal el&, buffer As Any) */
  321. int FAR pascal _export
  322. GetHugeEl(int hArray, long element, BYTE FAR *buffer)
  323.     {
  324.     BYTE _huge *ptr;    /* pointer to array element */
  325.     pDescrip   pArray;  /* pointer to array descriptor */
  326.  
  327.     DecCheckHandle
  328.  
  329.     /* point to proper descriptor */
  330.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  331.  
  332.     CheckNotAllocYet
  333.     CheckSubscript(element)
  334.  
  335.     /* calculate pointer to element */
  336.     ptr = (BYTE _huge *) GlobalLock(pArray -> handle);
  337.  
  338.     /* add offset of element */
  339.     ptr += HugeElementOffset(element, pArray->perseg, pArray->recsize);
  340.  
  341.     /* copy data */
  342.     _fmemcpy(buffer, ptr, pArray -> recsize);
  343.  
  344.     GlobalUnlock(pArray -> handle);
  345.     LocalUnlock(hLocalMem);
  346.     return HA_OK;
  347.     }
  348.  
  349. /* Same as GetHugeEl, except that it can copy multiple elements at one time. */
  350. /* VBI:  Declare Function MSHugeGetNum% Lib "hugearr.dll" Alias "GetHugeNEl" (ByVal Index%, ByVal el&, ByVal nelem%, buffer As Any) */
  351. /* VBB:  Declare Function GetHugeNEl% Lib "hugearr.dll" (ByVal Index%, ByVal el&, ByVal nelem%, buffer As Any) */
  352. int FAR pascal _export
  353. GetHugeNEl(int hArray, long element, int nelem, BYTE FAR *buffer)
  354.     {
  355.     BYTE _huge *ToBegin;
  356.     BYTE _huge *ToElem;   /* pointer to array element */
  357.     pDescrip   pArray;    /* pointer to array descriptor */
  358.  
  359.     DecCheckHandle
  360.  
  361.     /* point to proper descriptor */
  362.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  363.  
  364.     CheckNotAllocYet
  365.     CheckSubscript(element + nelem - 1)
  366.  
  367.     /* calculate pointer to element */
  368.     ToBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
  369.  
  370.     while (nelem-- > 0)
  371.         {
  372.         ToElem = ToBegin + HugeElementOffset(element, pArray->perseg, pArray->recsize);
  373.  
  374.         /* copy one element of data */
  375.         _fmemcpy(buffer, ToElem, pArray -> recsize);
  376.  
  377.         /* increment pointer to VB array to point to next element. */
  378.         buffer += pArray -> recsize;
  379.         element ++;
  380.         }
  381.  
  382.     GlobalUnlock(pArray -> handle);
  383.     LocalUnlock(hLocalMem);
  384.     return HA_OK;
  385.     }
  386.  
  387. /********************************************************************
  388. * SetHugeEl -                                                       *
  389. *   Sets the value of an array element.  This routine is exactly    *
  390. * the same as 'GetHugeEl' except that the memory copy is resversed. *
  391. ********************************************************************/
  392. /* VBI:  Declare Function MSHugeSet% Lib "hugearr.dll" Alias "SetHugeEl" (ByVal Index%, ByVal el&, buffer As Any) */
  393. /* VBB:  Declare Function SetHugeEl% Lib "hugearr.dll" (ByVal Index%, ByVal el&, buffer As Any) */
  394. int FAR pascal _export
  395. SetHugeEl(int hArray, long element, BYTE FAR *buffer)
  396.     {
  397.     BYTE _huge *ptr;    /* pointer to array element */
  398.     pDescrip   pArray;  /* pointer to array descriptor */
  399.  
  400.     DecCheckHandle
  401.  
  402.     /* point to proper descriptor */
  403.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  404.  
  405.     CheckNotAllocYet
  406.     CheckSubscript(element)
  407.  
  408.     /* calculate pointer to element */
  409.     ptr = (BYTE _huge *) GlobalLock(pArray -> handle);
  410.  
  411.     /* add offset of element */
  412.     ptr += HugeElementOffset(element, pArray->perseg, pArray->recsize);
  413.  
  414.     /* copy data */
  415.     _fmemcpy(ptr, buffer, pArray -> recsize);
  416.  
  417.     GlobalUnlock(pArray -> handle);
  418.     LocalUnlock(hLocalMem);
  419.     return HA_OK;
  420.     }
  421.  
  422. /* Same as SetHugeEl, except that it can copy multiple elements at one time. */
  423. /* VBI:  Declare Function MSHugeSetNum% Lib "hugearr.dll" Alias "SetHugeNEl" (ByVal Index%, ByVal el&, ByVal nelem%, buffer As Any) */
  424. /* VBB:  Declare Function SetHugeNEl% Lib "hugearr.dll" (ByVal Index%, ByVal el&, ByVal nelem%, buffer As Any) */
  425. int FAR pascal _export
  426. SetHugeNEl(int hArray, long element, int nelem, BYTE FAR *buffer)
  427.     {
  428.     BYTE _huge *ToBegin;
  429.     BYTE _huge *ToElem;   /* pointer to array element */
  430.     pDescrip   pArray;    /* pointer to array descriptor */
  431.  
  432.     DecCheckHandle
  433.  
  434.     /* point to proper descriptor */
  435.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  436.  
  437.     CheckNotAllocYet
  438.     CheckSubscript(element + nelem - 1)
  439.  
  440.     /* calculate pointer to element */
  441.     ToBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
  442.  
  443.     while (nelem-- > 0)
  444.         {
  445.         ToElem = ToBegin + HugeElementOffset(element, pArray->perseg, pArray->recsize);
  446.  
  447.         /* copy one element of data */
  448.         _fmemcpy(ToElem, buffer, pArray -> recsize);
  449.  
  450.         /* increment pointer to VB array to point to next element. */
  451.         buffer += pArray -> recsize;
  452.         element ++;
  453.         }
  454.  
  455.     GlobalUnlock(pArray -> handle);
  456.     LocalUnlock(hLocalMem);
  457.     return HA_OK;
  458.     }
  459.  
  460. /********************************************************************
  461. * HugeErase -                                                       *
  462. *   Deletes an array and marks it as free in the descriptor table.  *
  463. * 'hArray' is the array to erase.                                   *
  464. ********************************************************************/
  465. /* VBI:  Declare Function MSHugeErase% Lib "hugearr.dll" Alias "HugeErase" (ByVal hArray%) */
  466. /* VBB:  Declare Function HugeErase% Lib "hugearr.dll" (ByVal hArray%) */
  467. int FAR pascal _export
  468. HugeErase(int hArray)
  469.     {
  470.     pDescrip pArray;  /* pointer to array descriptor */
  471.  
  472.     DecCheckHandle
  473.  
  474.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  475.  
  476.     CheckNotAllocYet
  477.  
  478.     /* free the memory */
  479.     GlobalFree(pArray -> handle);
  480.     pArray -> handle = NULL;
  481.  
  482.     LocalUnlock(hLocalMem);
  483.     return HA_OK;
  484.     }
  485.  
  486. /********************************************************************
  487. * NumHugeArrays -                                                   *
  488. *   Returns the number of free entries in the array descriptor table*
  489. ********************************************************************/
  490. /* VBI:  Declare Function MSHugeNumArrays% Lib "hugearr.dll" Alias "NumHugeArrays" () */
  491. /* VBB:  Declare Function NumHugeArrays% Lib "hugearr.dll" () */
  492. int FAR pascal _export
  493. NumHugeArrays(void)
  494.     {
  495.     pDescrip pArray;  /* pointer to current descriptor */
  496.     int num, i;       /* number free so far */
  497.  
  498.     pArray = (pDescrip) LocalLock(hLocalMem);
  499.     for (i = 0, num = 0; i < NumArrays; i++, pArray++)
  500.         if (pArray -> handle == NULL)
  501.             ++num;
  502.  
  503.     LocalUnlock(hLocalMem);
  504.     return num;
  505.     }
  506.  
  507.  
  508. /********************************************************************
  509. * HugeUbound -                                                      *
  510. *   Returns the upper bound of a given array                        *
  511. ********************************************************************/
  512. /* VBI:  Declare Function MSHugeUbound& Lib "hugearr.dll" Alias "HugeUBound" (ByVal hArray%) */
  513. /* VBB:  Declare Function HugeUbound& Lib "hugearr.dll" (ByVal hArray%) */
  514. long FAR pascal _export
  515. HugeUbound(int hArray)
  516.     {
  517.     pDescrip pArray;  /* pointer to array descriptor */
  518.     long ubound;      /* upper bound of array */
  519.  
  520.     DecCheckHandle
  521.  
  522.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  523.  
  524.     CheckNotAllocYet
  525.  
  526.     ubound = pArray -> ubound;
  527.     LocalUnlock(hLocalMem);
  528.  
  529.     return ubound;
  530.     }
  531.  
  532.  
  533. /********************************************************************
  534. * HugeInt -                                                         *
  535. *   Same as GetHugeEl except that it explicitly returns an integer. *
  536. * Use this function when you are in an expression such as:          *
  537. *           i% = 5 * HugeInt(4, 5)                                  *
  538. *                                                                   *
  539. * NOTE: Because the user could store anything in the array element, *
  540. *       they will not know if the value returned is a real value or *
  541. *       if an error occured.  Use GetHugeEl if the error code must  *
  542. *       be checked.                                                 *
  543. ********************************************************************/
  544. /* VBI:  Declare Function MSHugeGetInt% Lib "hugearr.dll" Alias "HugeInt" (ByVal hArray%, ByVal el&) */
  545. /* VBB:  Declare Function HugeInt% Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
  546. int FAR pascal _export
  547. HugeInt(int hArray, long element)
  548.     {
  549.     int retval;
  550.  
  551.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  552.     return retval;
  553.     }
  554.  
  555. /********************************************************************
  556. * HugeLong -                                                        *
  557. *   Returns an element of a long integer array.  (re. HugeInt)      *
  558. ********************************************************************/
  559. /* VBI:  Declare Function MSHugeGetLong& Lib "hugearr.dll" Alias "HugeLong" (ByVal hArray%, ByVal el&) */
  560. /* VBB:  Declare Function HugeLong& Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
  561. long FAR pascal _export
  562. HugeLong(int hArray, long element)
  563.     {
  564.     long    retval;
  565.  
  566.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  567.     return retval;
  568.     }
  569.  
  570. /********************************************************************
  571. * HugeSingle -                                                      *
  572. *   Returns an element of a single precesion array.  (re. HugeInt)  *
  573. ********************************************************************/
  574. /* VBI:  Declare Function MSHugeGetSingle! Lib "hugearr.dll" Alias "HugeSingle" (ByVal hArray%, ByVal el&) */
  575. /* VBB:  Declare Function HugeSingle! Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
  576. float FAR pascal _export
  577. HugeSingle(int hArray, long element)
  578.     {
  579.     float retval;
  580.  
  581.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  582.     return retval;
  583.     }
  584.  
  585. /********************************************************************
  586. * HugeDouble -                                                      *
  587. *   Returns an element of a double precesion array.  (re. HugeInt)  *
  588. ********************************************************************/
  589. /* VBI:  Declare Function MSHugeGetDouble# Lib "hugearr.dll" Alias "HugeDouble" (ByVal hArray%, ByVal el&) */
  590. /* VBB:  Declare Function HugeDouble# Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
  591. double FAR pascal _export
  592. HugeDouble(int hArray, long element)
  593.     {
  594.     double  retval;
  595.  
  596.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  597.     return retval;
  598.     }
  599.  
  600. /********************************************************************
  601. * HugeCurrency -                                                    *
  602. *   Returns an element of a currency array.  (re. HugeInt)          *
  603. ********************************************************************/
  604. /* VBI:  Declare Function MSHugeGetCurrency@ Lib "hugearr.dll" Alias "HugeCurrency" (ByVal hArray%, ByVal el&) */
  605. /* VBB:  Declare Function HugeCurrency@ Lib "hugearr.dll" (ByVal hArray%, ByVal el&) */
  606. currency FAR pascal _export
  607. HugeCurrency(int hArray, long element)
  608.     {
  609.     currency retval;
  610.  
  611.     GetHugeEl(hArray, element, (BYTE FAR *) &retval);
  612.     return retval;
  613.     }
  614.  
  615.  
  616. #ifdef DEBUG
  617. /* Functions left from when I was debugging my own HugeRedim problems. --SJS */
  618. /* Return 1 if the last HugeRedim successfully called GlobalRealloc, or
  619.    return 0 if it had to call HugeAlloc and copy over elements. */
  620. int FAR pascal _export
  621. HugeRedimOk(int hArray)
  622.     {
  623.     pDescrip pArray;  /* pointer to array descriptor */
  624.     int      RtnVal;
  625.  
  626.     DecCheckHandle
  627.  
  628.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  629.  
  630.     RtnVal = pArray -> redim;
  631.  
  632.     LocalUnlock(hLocalMem);
  633.     return RtnVal;
  634.     }
  635.  
  636. /* Return actual size in bytes of the global memory block that was
  637.    allocated for storing array elements */
  638. long FAR pascal _export
  639. HugeSize(int hArray)
  640.     {
  641.     pDescrip pArray;  /* pointer to array descriptor */
  642.     long     RtnVal;
  643.  
  644.     DecCheckHandle
  645.  
  646.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  647.  
  648.     RtnVal = pArray -> bsize;
  649.  
  650.     LocalUnlock(hLocalMem);
  651.     return RtnVal;
  652.     }
  653. #endif
  654.  
  655. /********************************************************************
  656. *   HugeSave - Saves the specified number of elements to a file     *
  657. *              Returns the number of items saved.                   *
  658. *                                                                   *
  659. *   NB!   HugeSave does not Erase the Huge Array.                   *
  660. ********************************************************************/
  661. /* VBI:  Declare Function MSHugeSave& Lib "hugearr.dll" Alias "HugeSave" (ByVal hArray%, ByVal NEl&, ByVal RecLen%, ByVal Fn$) */
  662. /* VBB:  Declare Function HugeSave& Lib "hugearr.dll" (ByVal hArray%, ByVal NEl&, ByVal RecLen%, ByVal Fn$) */
  663. long FAR pascal _export
  664. HugeSave(int hArray, long nelements, int OutLen, LPSTR FileSpec)
  665.     {
  666.     int        hSaveFile;  /* handle to the save file */
  667.     BYTE _huge *FmBegin;   /* pointer for first element */
  668.     BYTE _huge *FmElem;    /* pointer to array element */
  669.     long       element;    /* element in the huge array */
  670.     pDescrip   pArray;     /* pointer to array descriptor */
  671.  
  672.     DecCheckHandle
  673.  
  674.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  675.  
  676.     CheckNotAllocYet
  677.  
  678.     if (pArray -> ubound + 1 < nelements || nelements < 0)
  679.         {
  680.         /* subscript out of range */
  681.         LocalUnlock(hLocalMem);
  682.         return HA_SUBSCRIPT;
  683.         }
  684.  
  685.     /* Open the file */
  686.     hSaveFile = _lopen(FileSpec, OF_WRITE);
  687.     if (hSaveFile < 0)
  688.         {
  689.         LocalUnlock(hLocalMem);
  690.         return HA_FILEOPENERROR;
  691.         }
  692.  
  693.     /* calculate pointer to element */
  694.     FmBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
  695.  
  696.     for(element = 0L; element < nelements; element++)
  697.         {
  698.         FmElem = FmBegin + HugeElementOffset(element, pArray->perseg, pArray->recsize);
  699.  
  700.         /* Write out the record */
  701.         if(_lwrite(hSaveFile, FmElem, OutLen) < 0)
  702.             {
  703.             element = HA_FILEWRITEERROR;
  704.             break;
  705.             }
  706.         }
  707.  
  708.     /* Wrap up and return */
  709.     GlobalUnlock(pArray -> handle);
  710.     LocalUnlock(hLocalMem);
  711.     _lclose(hSaveFile);
  712.     return element;
  713.     }
  714.  
  715. /********************************************************************
  716. *   HugeLoad - Loads a Huge Array from the specified file           *
  717. *              Returns the number of elements loaded                *
  718. *                                                                   *
  719. *   NB!  The array must have been allocated and be of sufficient    *
  720. *   NB!  size to hold the array.                                    *
  721. ********************************************************************/
  722. /* VBI:  Declare Function MSHugeLoad& Lib "hugearr.dll" Alias "HugeLoad" (ByVal hArray%, ByVal RecLen%, ByVal Fn$) */
  723. /* VBB:  Declare Function HugeLoad& Lib "hugearr.dll" (ByVal hArray%, ByVal RecLen%, ByVal Fn$) */
  724. long FAR pascal _export
  725. HugeLoad(int hArray, int InLen, LPSTR FileSpec)
  726.     {
  727.     int        BytesRead;  /* number of bytes read from the file */
  728.     int        hLoadFile;  /* handle to the save file */
  729.     BYTE _huge *ToBegin;   /* pointer for first element */
  730.     BYTE _huge *ToElem;    /* pointer to array element */
  731.     long       element;    /* element in the huge array */
  732.     pDescrip   pArray;     /* pointer to array descriptor */
  733.  
  734.     DecCheckHandle
  735.  
  736.     pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
  737.  
  738.     CheckNotAllocYet
  739.  
  740.     /* Open the file */
  741.     if((hLoadFile = _lopen(FileSpec, OF_READ)) < 0)
  742.         {
  743.         LocalUnlock(hLocalMem);
  744.         return HA_FILEOPENERROR;
  745.         }
  746.  
  747.     ToBegin = (BYTE _huge *) GlobalLock(pArray -> handle);
  748.  
  749.     for(element = 0L; element <= pArray -> ubound ; element++)
  750.         {
  751.         /* calculate pointer to element */
  752.         ToElem = ToBegin + HugeElementOffset(element, pArray->perseg, pArray->recsize);
  753.  
  754.         /* Read the record */
  755.         BytesRead = _lread(hLoadFile, ToElem, InLen);
  756.  
  757.         if (BytesRead < 0)
  758.             element = HA_FILEREADERROR;
  759.         if (BytesRead <= 0)
  760.             break;
  761.         }
  762.  
  763.     /* Wrap up and return */
  764.     GlobalUnlock(pArray -> handle);
  765.     LocalUnlock(hLocalMem);
  766.     _lclose(hLoadFile);
  767.     return element;
  768.     }
  769.